home *** CD-ROM | disk | FTP | other *** search
/ Ian & Stuart's Australian Mac 1993 September / clonecd / September 93.img / Archives / Fun, Tricks & Hacks / Hacks & Tricks - CARE / Flipper / Flipper Code / flipScreen.c < prev    next >
Text File  |  1993-06-17  |  18KB  |  886 lines

  1. /*
  2.     flipScreen.c
  3.     
  4.     copyright © 1993 by Ken Hornak, Jr.
  5.     2120 Garden Homes Ct
  6.     Ann Arbor, MI 48103
  7.     
  8.     GEnie: K.Hornak, AppleLink: MEDIMAGE
  9.     (I'm on AOL and CompuServe as well, but I forgot the accounts.)
  10.     
  11.     Permission is granted to use this code in your programs as long
  12.     as the copyright is retained in the code. Please see the documentation
  13.     as to how we actually do the flip.
  14.     
  15.     If you do something really cool with it, I hope you'll share it
  16.     with me. Some day I'd like to add vertical and diagonal axis flips
  17.     as well. It should also be made a small system extension instead of
  18.     a full app, but that can wait until another day.
  19.     
  20.     Typical usage of this code would be:
  21.     
  22.                     setupToFlip(&myRec.myGlobals, FALSE);
  23.                     flipIt(&myRec.myGlobals, 1, 2);
  24.                     
  25.                     Delay(30, &ticksNow);
  26.                     
  27.                     flipIt(&myRec.myGlobals, 1, 1);
  28.                     cleanupFlip(&myRec.myGlobals);
  29.  
  30.                     killFlip();    // before exiting to remove the sleep task
  31.     
  32.     Note that the code makes provision for segmenting the screen into
  33.     an array of panels and flipping those as well, however I seemed
  34.     to have broken that feature along the way somewhere and am not
  35.     going to fix it for a while.
  36.     
  37.     I sincerely apologize for the strange state of this code, after all
  38.     it was written at MacHack and was truly thrown together with little
  39.     thought as to organization, commenting, parameter passing, naming,
  40.     you name it. This definitely does not reflect my day-to-day programming
  41.     (except for any bugs you may find).
  42. */
  43.  
  44.  
  45. #include <stdio.h>
  46. #include <GestaltEqu.h>
  47.  
  48.  
  49. #include "flipScreen.h"
  50.  
  51.  
  52. #define ROTATE_STEPS            20
  53.  
  54. #define abs(x)                ((x) > 0 ? (x) : (-(x)))
  55. #define RECT_HEIGHT(r)        abs((r).bottom-(r).top)
  56. #define RECT_WIDTH(r)        abs((r).right-(r).left)
  57.  
  58.  
  59. /*
  60.     Globals
  61. */
  62.  
  63. Boolean            gHasPowerManager = FALSE;
  64. MySleepInfo        myRec;
  65.  
  66.  
  67. /*
  68.     Prototypes
  69. */
  70.  
  71. GWorldPtr            getScreen            (void);
  72. void                getScreenRect        (Rect* theRect);
  73. void                getScreenSection    (ScreenPanel* thePanel, Rect* area);
  74. void                rotatePanel            (ScreenPanel* thePanel, short h, short v, short how);
  75. void                rotatePanel2        (ScreenPanel* thePanel, short h, short v);
  76. Boolean                lockPanels            (FlipInfo* gFlipGlobals);
  77.  
  78.  
  79. /*
  80.     initFlipper
  81. */
  82. void
  83. initFlipper(void)
  84. {
  85.     OSErr        err = noErr;
  86.     long        response;
  87.     
  88.     
  89.     myRec.myGlobals.gNumRows = 1;
  90.     myRec.myGlobals.gNumCols = 1;
  91.     myRec.myGlobals.gNumPanels = myRec.myGlobals.gNumRows *
  92.             myRec.myGlobals.gNumCols;
  93.     
  94.     // Check for the Power Manager.
  95.     
  96.     err = Gestalt(gestaltPowerMgrAttr, &response);
  97.     
  98.     if (err == noErr)
  99.     {
  100.         if ((response >> gestaltPMgrExists) & 0x00000001)
  101.             gHasPowerManager = TRUE;
  102.     }
  103.  
  104.  
  105.     if (gHasPowerManager)
  106.     {
  107.         asm
  108.         {
  109.             move.l        a5,myRec.myA5
  110.         }
  111.         
  112.         
  113.         // set up the record before installing onto the sleep queue
  114.         myRec.sleepRec.sleepQLink = 0;
  115.         myRec.sleepRec.sleepQType = slpQType;    // sleep queue type, 16
  116.         myRec.sleepRec.sleepQProc = MySleepRtn;    // address of some sleep routine
  117.         myRec.sleepRec.sleepQFlags = 0;         // reserved field
  118.     
  119.         SleepQInstall(&myRec.sleepRec);        // install
  120.     }
  121.     
  122. } // initFlipper
  123.  
  124.  
  125.  
  126. /*
  127.     setupToFlip
  128. */
  129. void
  130. setupToFlip(FlipInfo* gFlipGlobals, Boolean grayScreen)
  131. {
  132.     GrafPtr            oldPort;
  133.     short            i;
  134.     short            rotateSteps;
  135.     CGrafPtr        wPort;
  136.     Rect            screenRect;
  137.     short            curPanel;
  138.     Rect            panelRect;
  139.     short            j;
  140.     Boolean            lockSuccess;
  141.  
  142. #ifdef DEBUG
  143.     unsigned char    str[256];
  144. #endif
  145.  
  146.  
  147.     GetPort(&oldPort);
  148.     
  149.     GetCWMgrPort(&wPort);
  150.  
  151.     getScreenRect(&screenRect);
  152.     
  153.     rotateSteps = ROTATE_STEPS;
  154.     
  155.     // Create the gworlds containing the screen sections.
  156.     
  157.     curPanel = 0;
  158.     gFlipGlobals->gPanelHeight = RECT_HEIGHT(screenRect) / gFlipGlobals->gNumRows;
  159.     gFlipGlobals->gPanelWidth = RECT_WIDTH(screenRect) / gFlipGlobals->gNumCols;
  160.     
  161.     for (i=0; i<gFlipGlobals->gNumRows; i++)
  162.     {
  163.         panelRect.top = screenRect.top + i * gFlipGlobals->gPanelHeight;
  164.         panelRect.bottom = panelRect.top + gFlipGlobals->gPanelHeight;
  165.         
  166.         for (j=0; j<gFlipGlobals->gNumCols; j++)
  167.         {
  168.             panelRect.left = screenRect.left + j * gFlipGlobals->gPanelWidth;
  169.             panelRect.right = panelRect.left + gFlipGlobals->gPanelWidth;
  170.             
  171.             if (j == gFlipGlobals->gNumCols-1)
  172.                 panelRect.right = screenRect.right;
  173.             
  174.             if (i == gFlipGlobals->gNumRows-1)
  175.                 panelRect.bottom = screenRect.bottom;
  176.  
  177. #ifdef DEBUG
  178.     sprintf((char*) str, "ht: %hd, wd: %hd, l: %hd, t: %hd, r: %hd, b: %hd",
  179.             gFlipGlobals->gPanelHeight, gFlipGlobals->gPanelWidth,
  180.             panelRect.left, panelRect.top, panelRect.right, panelRect.bottom);
  181.     CtoPstr((char*) str);
  182.     DebugStr(str);
  183. #endif
  184.         
  185.             getScreenSection(&gFlipGlobals->gThePanels[curPanel], &panelRect);
  186.             
  187.             curPanel++;
  188.         } // for j
  189.     } // for i
  190.     
  191.     lockSuccess = lockPanels(gFlipGlobals);
  192.     
  193.     if (!lockSuccess)
  194.         DebugStr("\pCouldn't lock the panels.");
  195.     
  196.     SetPort((GrafPtr) wPort);
  197.     ClipRect(&wPort->portRect);
  198.     
  199.     if (grayScreen)
  200.     {
  201.         // Make the whole screen gray.
  202.         
  203.         FillRect(&wPort->portRect, gray);
  204.     }
  205.  
  206.     SetPort(oldPort);
  207.     
  208. } // setupToFlip
  209.  
  210.  
  211.  
  212. /*
  213.     flipIt
  214. */
  215. void
  216. flipIt(FlipInfo* gFlipGlobals, short how, short direction)
  217. {
  218.     GrafPtr            oldPort;
  219.     short            h;
  220.     short            v;
  221.     CGrafPtr        wPort;
  222.     short            i;
  223.     short            j;
  224.     short            rotateStep;
  225.     short            rotateSteps;
  226.     PixMapHandle    pmap;
  227.     long            thisRotateTime, rotateTime, numRotates;
  228.     
  229. #ifdef DEBUG
  230.     Str255 str;
  231. #endif
  232.  
  233.  
  234.     GetPort(&oldPort);
  235.         
  236.     GetCWMgrPort(&wPort);
  237.     
  238.     rotateSteps = ROTATE_STEPS;
  239.  
  240.     // Make sure the screen gets blanked.
  241.     
  242.     SetPort((GrafPtr) wPort);
  243.     
  244.     ForeColor(blackColor);
  245.     BackColor(whiteColor);
  246.     
  247.     // Setup to rotate each section.
  248.     
  249.     rotateStep = gFlipGlobals->gPanelHeight / rotateSteps;
  250.     
  251.     HideCursor();
  252.  
  253.     numRotates = 0;
  254.     
  255.     if (direction == 1)
  256.     {
  257.         for (h=1; h<=gFlipGlobals->gPanelHeight; h+=rotateStep)
  258.         {
  259.             v = ((gFlipGlobals->gPanelHeight - h) * 3) / 4;
  260.             
  261.             for (i=0; i<gFlipGlobals->gNumPanels; i++)
  262.             {
  263.                 rotatePanel(&gFlipGlobals->gThePanels[i], h, v, how);
  264.                 
  265.                 // Now blit the rotated section to the screen.
  266.                 
  267.                 SetPort((GrafPtr) wPort);
  268.                 
  269.                 pmap = gFlipGlobals->gThePanels[i].rotatedPMap;
  270.                 
  271.                 CopyBits((BitMapPtr) *pmap, (BitMapPtr) *wPort->portPixMap,
  272.                         &gFlipGlobals->gThePanels[i].rotatedGWorld->portRect,
  273.                         &gFlipGlobals->gThePanels[i].itsGWorld->portRect, srcCopy, NULL);
  274.             } // for i
  275.         } // for h
  276.  
  277.         // Finish by putting the exact image back.
  278.         
  279.         for (i=0; i<gFlipGlobals->gNumPanels; i++)
  280.         {
  281.             // Now blit the correct section to the screen.
  282.             
  283.             SetPort((GrafPtr) wPort);
  284.             
  285.             pmap = GetGWorldPixMap(gFlipGlobals->gThePanels[i].itsGWorld);
  286.             
  287.             if (LockPixels(pmap))
  288.             {
  289.                 CopyBits((BitMapPtr) *pmap, (BitMapPtr) *wPort->portPixMap,
  290.                         &gFlipGlobals->gThePanels[i].itsGWorld->portRect,
  291.                         &gFlipGlobals->gThePanels[i].itsGWorld->portRect, srcCopy, NULL);
  292.                     
  293.                 UnlockPixels(pmap);
  294.             }
  295.         } // for i
  296.     
  297.     }
  298.     else
  299.     {
  300.         for (h=gFlipGlobals->gPanelHeight-rotateStep; h>0; h-=rotateStep)
  301.         {
  302.             v = ((gFlipGlobals->gPanelHeight - h) * 3) / 4;
  303.             
  304.             for (i=0; i<gFlipGlobals->gNumPanels; i++)
  305.             {
  306.                 rotatePanel(&gFlipGlobals->gThePanels[i], h, v, how);
  307.     
  308.                 // Now blit the rotated section to the screen.
  309.                 
  310.                 SetPort((GrafPtr) wPort);
  311.                 
  312.                 pmap = gFlipGlobals->gThePanels[i].rotatedPMap;
  313.                 
  314.                 CopyBits((BitMapPtr) *pmap, (BitMapPtr) *wPort->portPixMap,
  315.                         &gFlipGlobals->gThePanels[i].rotatedGWorld->portRect,
  316.                         &gFlipGlobals->gThePanels[i].itsGWorld->portRect, srcCopy, NULL);
  317.             } // for i
  318.         } // for h
  319.         
  320.         // Make the whole screen gray.
  321.         
  322.         FillRect(&wPort->portRect, gray);
  323.     }
  324.     
  325.     SetPort(oldPort);
  326.     
  327.     ShowCursor();
  328.     
  329. } // flipIt
  330.  
  331.  
  332.  
  333. /*
  334.     cleanupFlip
  335. */
  336. void
  337. cleanupFlip(FlipInfo* gFlipGlobals)
  338. {
  339.     short            i;
  340.     
  341.     
  342.     // Dispose of everything.
  343.     
  344.     for (i=0; i<gFlipGlobals->gNumPanels; i++)
  345.     {
  346.         DisposeGWorld(gFlipGlobals->gThePanels[i].itsGWorld);
  347.         gFlipGlobals->gThePanels[i].itsGWorld = NULL;
  348.         
  349.         DisposeGWorld(gFlipGlobals->gThePanels[i].rotatedGWorld);
  350.         gFlipGlobals->gThePanels[i].rotatedGWorld = NULL;
  351.     }
  352.  
  353. } // cleanupFlip
  354.  
  355.  
  356.  
  357. /*
  358.     lockPanels
  359. */
  360. Boolean
  361. lockPanels(FlipInfo* gFlipGlobals)
  362. {
  363.     short        i;
  364.  
  365.     
  366.     for (i=0; i<gFlipGlobals->gNumPanels; i++)
  367.     {
  368.         gFlipGlobals->gThePanels[i].itsPMap =
  369.                 GetGWorldPixMap(gFlipGlobals->gThePanels[i].itsGWorld);
  370.         
  371.         if (!LockPixels(gFlipGlobals->gThePanels[i].itsPMap))
  372.             return(FALSE);
  373.             
  374.         gFlipGlobals->gThePanels[i].rotatedPMap =
  375.                 GetGWorldPixMap(gFlipGlobals->gThePanels[i].rotatedGWorld);
  376.         
  377.         if (!LockPixels(gFlipGlobals->gThePanels[i].rotatedPMap))
  378.             return(FALSE);
  379.     } // for i
  380.     
  381.     return(TRUE);
  382.     
  383. } // lockPanels
  384.  
  385.  
  386.  
  387. /*
  388.     rotatePanel
  389. */
  390. void
  391. rotatePanel(ScreenPanel* thePanel, short h, short v, short how)
  392. {
  393.     PixMapHandle        pmap;
  394.     CGrafPtr            oldPort;
  395.     GDHandle            gdh;
  396.     PixMapHandle        rotatedPMap;
  397.     short                width;
  398.     short                height;
  399.     short                row;
  400.     short                col;
  401.     Rect                theRect;
  402.     short                x;
  403.     short                y;
  404.     short                midY;
  405.     short                midX;
  406.     short                y1, y2, deltaX;
  407.     Rect                srcRect, dstRect;
  408.     Pattern                myGray = { 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55, 0xaa, 0x55 };
  409.  
  410.     short                bytesPerRow;
  411.     short                bytesInDstRow;
  412.     Ptr                    srcPtr;
  413.     Ptr                    dstPtr;
  414.     short                pixelDepth;
  415.     short                realBytesPerRow;
  416.     
  417.  
  418.     pmap = thePanel->itsPMap;
  419.  
  420.     // Get the current port settings.
  421.     
  422.     GetGWorld(&oldPort, &gdh);
  423.     
  424.     // Clear the destination gworld.
  425.     
  426.     rotatedPMap = thePanel->rotatedPMap;
  427.     
  428.     SetGWorld(thePanel->rotatedGWorld, thePanel->rotatedGDevice);
  429.     
  430.     theRect = thePanel->itsGWorld->portRect;
  431.     
  432.     ForeColor(blackColor);
  433.     BackColor(whiteColor);
  434.     
  435.     FillRect(&theRect, myGray);
  436.     
  437.  
  438.     bytesPerRow = (**pmap).rowBytes & 0x3FFF;
  439.     srcPtr = GetPixBaseAddr(pmap);
  440.     dstPtr = GetPixBaseAddr(rotatedPMap);
  441.     pixelDepth = (**pmap).pixelSize;
  442.     
  443.     realBytesPerRow = RECT_WIDTH(theRect) * (long) pixelDepth / 8L;
  444.  
  445.     width = RECT_WIDTH(theRect);
  446.     height = RECT_HEIGHT(theRect);
  447.     
  448.     midY = (theRect.top + theRect.bottom) / 2;
  449.     
  450.     y1 = midY - h / 2;
  451.     y2 = y1 + h;
  452.     
  453.     srcRect.left = theRect.left;
  454.     srcRect.right = theRect.right;
  455.  
  456.     dstRect.top = y1;
  457.     dstRect.bottom = y1 + 1;
  458.  
  459.     dstPtr += (long) y1 * (long) bytesPerRow;
  460.  
  461.     for (row = y1; row <= y2; row++)
  462.     {
  463.         y = theRect.top + (long) height * (long) (row - y1) / h;
  464.         
  465.         deltaX = (long) v * (long) (row - y1) / (2 * h);
  466.         
  467.         dstRect.left = theRect.left + deltaX;
  468.         dstRect.right = theRect.right - deltaX;
  469.         
  470.         srcRect.top = y;
  471.         srcRect.bottom = y + 1;
  472.         
  473.         switch (how)
  474.         {
  475.             case 1:        // w/block move from both edges
  476.                 bytesInDstRow = (long) (dstRect.right - dstRect.left) * (long) pixelDepth / 8L;
  477.                 
  478.                     // Copy first part of src line
  479.                 BlockMove(srcPtr + (long) y * (long) bytesPerRow,
  480.                         dstPtr + (long) deltaX * (long) pixelDepth / 8L,
  481.                         bytesInDstRow / 2);
  482.         
  483.                     // Copy last part of src line
  484.                 BlockMove(srcPtr + (long) y * (long) bytesPerRow + (realBytesPerRow - bytesInDstRow / 2),
  485.                         dstPtr + (long) deltaX * (long) pixelDepth / 8L + bytesInDstRow / 2,
  486.                         bytesInDstRow / 2);
  487.                 
  488.                 dstPtr += bytesPerRow;
  489.                 break;
  490.             
  491.             case 3:        // w/block move from left edge
  492.                 bytesInDstRow = (long) (dstRect.right - dstRect.left) * (long) pixelDepth / 8L;
  493.                 
  494.                 if (0)    // copy from right
  495.                     BlockMove(srcPtr + (long) y * (long) bytesPerRow + (realBytesPerRow - bytesInDstRow),
  496.                             dstPtr + (long) deltaX * (long) pixelDepth / 8L,
  497.                             bytesInDstRow);
  498.                 else    // copy from left
  499.                     BlockMove(srcPtr + (long) y * (long) bytesPerRow,
  500.                             dstPtr + (long) deltaX * (long) pixelDepth / 8L,
  501.                             bytesInDstRow);
  502.                         
  503.                 dstPtr += bytesPerRow;
  504.                 break;
  505.             
  506.             case 2:        // w/copybits
  507.                 CopyBits((BitMapPtr) *pmap, (BitMapPtr) *rotatedPMap,
  508.                         &srcRect, &dstRect, srcCopy, NULL);
  509.                 break;
  510.                 
  511.             default:
  512.                 break;
  513.         } // switch
  514.         
  515.  
  516.         dstRect.top++;
  517.         dstRect.bottom++;
  518.     } // for row
  519.     
  520.     SetGWorld(oldPort, gdh);
  521.     
  522. } // rotatePanel
  523.  
  524.  
  525.  
  526. /*
  527.     rotatePanel2
  528. */
  529. void
  530. rotatePanel2(ScreenPanel* thePanel, short h, short v)
  531. {
  532.     PixMapHandle        pmap;
  533.     short                pixelSize;
  534.     short                bytesPerRow;
  535.     short                pixelsPerRow;
  536.     short                unusedBytes;
  537.     CGrafPtr            oldPort;
  538.     GDHandle            gdh;
  539.     PixMapHandle        rotatedPMap;
  540.     short                width;
  541.     short                height;
  542.     short                row;
  543.     short                col;
  544.     Rect                theRect;
  545.     short                x;
  546.     short                y;
  547.     short                midY;
  548.     short                midX;
  549.     unsigned char*        srcValPtr;
  550.     unsigned char*        dstValPtr;
  551.     short                y1, y2, deltaX;
  552.     Rect                srcRect, dstRect;
  553.     
  554.     
  555.     // First we need to know how many bytes might be unused at the
  556.     // end of each row of pixels.
  557.     
  558.     pmap = GetGWorldPixMap(thePanel->itsGWorld);
  559.     
  560.     if (!LockPixels(pmap))
  561.     {
  562.         DebugStr("\pCouldn't lock pixels in rotate2.");
  563.         return;
  564.     }
  565.  
  566. #if 0
  567.     pixelSize = (**pmap).pixelSize;
  568.     bytesPerRow = (**pmap).rowBytes & 0x3FFF;
  569.     pixelsPerRow = RECT_WIDTH((**pmap).bounds);
  570.     unusedBytes = (long) bytesPerRow - (long) pixelSize * (long) pixelsPerRow / 8L;
  571. #endif
  572.  
  573.     // Get the current port settings.
  574.     
  575.     GetGWorld(&oldPort, &gdh);
  576.     
  577.     // Clear the destination gworld.
  578.     
  579.     rotatedPMap = GetGWorldPixMap(thePanel->rotatedGWorld);
  580.     
  581.     if (!LockPixels(rotatedPMap))
  582.     {
  583.         DebugStr("\pCouldn't lock rotated pixels in rotate2.");
  584.         return;
  585.     }
  586.     
  587.     SetGWorld(thePanel->rotatedGWorld, thePanel->rotatedGDevice);
  588.     
  589.     theRect = thePanel->itsGWorld->portRect;
  590.     
  591.     BackColor(blackColor);
  592.     EraseRect(&theRect);
  593.     
  594.     ForeColor(blackColor);
  595.     BackColor(whiteColor);
  596.     
  597.     width = RECT_WIDTH(theRect);
  598.     height = RECT_HEIGHT(theRect);
  599.     
  600.     midY = (theRect.top + theRect.bottom) / 2;
  601.     
  602.     y1 = midY - h / 2;
  603.     y2 = y1 + h;
  604.     
  605.     for (row = y1; row <= y2; row++)
  606.     {
  607.         y = theRect.top + (long) height * (long) (row - y1) / h;
  608.         
  609.         deltaX = v * (y2 - row) / (2 * h);
  610.         
  611.         dstRect.left = theRect.left + deltaX;
  612.         dstRect.right = theRect.right - deltaX;
  613.         
  614.         dstRect.top = row;
  615.         dstRect.bottom = row + 1;
  616.         
  617.         srcRect.left = theRect.left;
  618.         srcRect.right = theRect.right;
  619.         srcRect.top = y;
  620.         srcRect.bottom = y + 1;
  621.  
  622. #if 0
  623.         if (srcRect.top < theRect.top)
  624.             DebugStr("\psrcRect.top is too small.");
  625.         if (srcRect.bottom > theRect.bottom)
  626.             DebugStr("\psrcRect.bottom is too great.");
  627. #endif
  628.  
  629.         CopyBits((BitMapPtr) *pmap, (BitMapPtr) *rotatedPMap,
  630.                 &srcRect, &dstRect, srcCopy, NULL);
  631.     } // for row
  632.     
  633.     UnlockPixels(pmap);
  634.     UnlockPixels(rotatedPMap);
  635.     
  636.     SetGWorld(oldPort, gdh);
  637.     
  638. } // rotatePanel2
  639.  
  640.  
  641.  
  642. /*
  643.     getScreenSection
  644. */
  645. void
  646. getScreenSection(ScreenPanel* thePanel, Rect* area)
  647. {
  648.     GDHandle        mainScreen = NULL;
  649.     QDErr            err = noErr;
  650.     GWorldPtr        theGWorld = NULL;
  651.     short            pixelDepth;
  652.     CTabHandle        cTable;
  653.     GWorldFlags        flags;
  654.     GDHandle        aGDevice;
  655.     GDHandle        gdh;
  656.     CGrafPtr        oldPort;
  657.     CGrafPtr        wPort;
  658.     PixMapHandle    gworldPMap;
  659.     Rect            boundsRect;
  660.     GWorldPtr        rotatedGWorld = NULL;
  661.  
  662. #ifdef DEBUG
  663.     Str255 str;
  664. #endif
  665.     
  666.     
  667.     mainScreen = GetMainDevice();
  668.     
  669.     aGDevice = mainScreen;
  670.     pixelDepth = (**(**mainScreen).gdPMap).pixelSize;
  671.     flags = noNewDevice | useTempMem;
  672.     cTable = (**(**mainScreen).gdPMap).pmTable;
  673.     boundsRect = *area;
  674.     
  675.     err = NewGWorld(&theGWorld, pixelDepth, &boundsRect, cTable, aGDevice, flags);
  676.     
  677.     if (err != noErr)
  678.     {
  679.         DebugStr("\pCouldn't create the gworld.");
  680.         return;
  681.     }
  682.         
  683.     // Create an identical gworld to hold the rotated image.
  684.     
  685.     err = NewGWorld(&rotatedGWorld, pixelDepth, &boundsRect, cTable, aGDevice, flags);
  686.     
  687.     if (err != noErr)
  688.     {
  689.         DebugStr("\pCouldn't create the rotated gworld.");
  690.         return;
  691.     }
  692.     
  693.     thePanel->rotatedGWorld = rotatedGWorld;
  694.     thePanel->rotatedGDevice = GetGWorldDevice(rotatedGWorld);
  695.     
  696.     // Get the main gworld's gdevice.
  697.     
  698.     aGDevice = GetGWorldDevice(theGWorld);
  699.     thePanel->itsGDevice = aGDevice;
  700.     
  701.     GetGWorld(&oldPort, &gdh);
  702.     SetGWorld(theGWorld, aGDevice);
  703.     
  704.     // Get the screen's port.
  705.     
  706.     GetCWMgrPort(&wPort);
  707.     
  708.     gworldPMap = GetGWorldPixMap(theGWorld);
  709.     
  710.     if (!LockPixels(gworldPMap))
  711.     {
  712.         DebugStr("\pCouldn't lock pixels while grabbing a section.");
  713.         return;
  714.     }
  715.         
  716.     // Copy the contents of the screen into the GWorld.
  717.  
  718. #ifdef DEBUG
  719.     sprintf((char*) str, "Copying from screen: l: %hd, t: %hd, r: %hd, b: %hd",
  720.             boundsRect.left, boundsRect.top, boundsRect.right, boundsRect.bottom);
  721.     CtoPstr((char*) str);
  722.     DebugStr(str);
  723. #endif
  724.  
  725.     CopyBits((BitMapPtr) *wPort->portPixMap, (BitMapPtr) *gworldPMap, &boundsRect, &boundsRect,
  726.             srcCopy, NULL);
  727.     
  728.     UnlockPixels(gworldPMap);
  729.     
  730.     SetGWorld(oldPort, gdh);
  731.     
  732.     thePanel->itsGWorld = theGWorld;
  733.     
  734. } // getScreenSection
  735.  
  736.  
  737.  
  738. /*
  739.     getScreenRect
  740. */
  741. void
  742. getScreenRect(Rect* theRect)
  743. {
  744.     GDHandle        mainScreen = NULL;
  745.  
  746.  
  747.     mainScreen = GetMainDevice();
  748.  
  749.     *theRect = (**mainScreen).gdRect;
  750.     
  751. } // getScreenRect
  752.  
  753.  
  754.  
  755. /*
  756.     getScreen
  757. */
  758. GWorldPtr
  759. getScreen(void)
  760. {
  761.     GDHandle        mainScreen = NULL;
  762.     QDErr            err = noErr;
  763.     GWorldPtr        theGWorld = NULL;
  764.     short            pixelDepth;
  765.     CTabHandle        cTable;
  766.     GWorldFlags        flags;
  767.     GDHandle        aGDevice;
  768.     GDHandle        gdh;
  769.     CGrafPtr        oldPort;
  770.     CGrafPtr        wPort;
  771.     PixMapHandle    gworldPMap;
  772.     Rect            boundsRect;
  773.     
  774.     
  775.     mainScreen = GetMainDevice();
  776.     
  777.     aGDevice = mainScreen;
  778.     pixelDepth = (**(**mainScreen).gdPMap).pixelSize;
  779.     flags = noNewDevice | useTempMem;
  780.     cTable = (**(**mainScreen).gdPMap).pmTable;
  781.     boundsRect = (**mainScreen).gdRect;
  782.     
  783.     err = NewGWorld(&theGWorld, pixelDepth, &boundsRect, cTable, aGDevice, flags);
  784.     
  785.     if (err != noErr)
  786.         return(NULL);
  787.     
  788.     aGDevice = GetGWorldDevice(theGWorld);
  789.     
  790.     GetGWorld(&oldPort, &gdh);
  791.     SetGWorld(theGWorld, aGDevice);
  792.     
  793.     // Get the screen's port.
  794.     
  795.     GetCWMgrPort(&wPort);
  796.     
  797.     gworldPMap = GetGWorldPixMap(theGWorld);
  798.     
  799.     if (!LockPixels(gworldPMap))
  800.         return(NULL);
  801.         
  802.     // Copy the contents of the screen into the GWorld.
  803.     
  804.     CopyBits((BitMapPtr) *wPort->portPixMap, (BitMapPtr) *gworldPMap, &boundsRect, &boundsRect,
  805.             srcCopy, NULL);
  806.     
  807.     UnlockPixels(gworldPMap);
  808.     
  809.     SetGWorld(oldPort, gdh);
  810.     
  811.     return(theGWorld);
  812.     
  813. } // getScreen
  814.  
  815.  
  816.  
  817. /*
  818.     killFlip
  819. */
  820. void
  821. killFlip(void)
  822. {
  823.  
  824.     SleepQRemove(&myRec.sleepRec);
  825.  
  826. } // killFlip
  827.  
  828.  
  829.  
  830. /*
  831.     MySleepRtn
  832. */
  833. long
  834. MySleepRtn(void)
  835. {
  836.     long            reason;
  837.     MySleepInfo*    info;
  838.     long            theA5;
  839.     
  840.     
  841.     // D0 contains the reason we're being called.
  842.     
  843.     asm
  844.     {
  845.         move.l        D0,reason
  846.         move.l        A0,info
  847.     }
  848.     
  849.     theA5 = info->myA5;
  850.     
  851.     asm
  852.     {
  853.         move.l        theA5,a5
  854.     }
  855.     
  856.         
  857.     switch (reason)
  858.     {
  859.         case 1:        // sleep request
  860.         case 2:        // sleep demand
  861.             setupToFlip(&info->myGlobals, FALSE);
  862.             flipIt(&info->myGlobals, 1, 2);
  863.             break;
  864.         
  865.         case 3:        // wakeup demand
  866.             flipIt(&info->myGlobals, 1, 1);
  867.             cleanupFlip(&info->myGlobals);
  868.             break;
  869.         
  870.         default:
  871.             break;
  872.     } // switch
  873.     
  874.     return(0);    // always succeed
  875.     
  876. } // MySleepRtn
  877.  
  878.  
  879.  
  880.  
  881.  
  882.  
  883.  
  884.  
  885.  
  886.